#include "Global_Define.h"
#include "Global_Func/Sem/Sem_Deal.h"

/*互斥体定义*/
//pthread_mutex_t BakData_Mutex;					//< 主站定时向从站备份信号量
//pthread_mutex_t BakIO_Mutex;					//< 主站定时向从站备份IO硬点信号量
//pthread_mutex_t BcDPU_Mutex;					//< 主站定时广播DPU状态信号量
//pthread_mutex_t BcAVIO_Mutex;					//< 主站定时广播模拟量硬点信号量
//pthread_mutex_t BcDVIO_Mutex;					//< 主站定时广播数字量硬点信号量
//pthread_mutex_t BcSama_Mutex;					//< 主站定时广播SAMA参数信号量
//pthread_mutex_t BcSamaIO_Mutex;				//< 主站定时广播SAMA软点信号量
//pthread_mutex_t ReadSamaIO_Mutex;				//< 读取软点信号量
//pthread_mutex_t BcSamaPara_Mutex;				//< 主站定时广播SAMA模块参数信号量
//pthread_mutex_t BcNetIO_Mutex;				//< 主站定时广播站间通讯模块DO、AO数据信号量
//pthread_mutex_t Calcu_Mutex;					//< 各运算周期定时运算信号量
//pthread_mutex_t IEC104_CallAll_Mutex;			//< IEC104主站通讯定时发送总召唤信号量
//pthread_mutex_t IEC104_Clock_Mutex;			//< IEC104主站通讯定时发送对时信号量

//< duan 20200205修改
/*信号量定义*/
sem_t* BakDataSemId;				//< 主站定时向从站备份信号量
sem_t* BakIOSemId;					//< 主站定时向从站备份IO硬点信号量
sem_t* BcDPUSemId;					//< 主站定时广播DPU状态信号量
sem_t* BcAVIOSemId;					//< 主站定时广播模拟量硬点信号量
sem_t* BcDVIOSemId;					//< 主站定时广播数字量硬点信号量
sem_t* BcSamaSemId;					//< 主站定时广播SAMA参数信号量
sem_t* BcSamaIOSemId;				//< 主站定时广播SAMA软点信号量
sem_t* ReadSamaIOSemId;				//< 读取软点信号量
sem_t* BcSamaParaSemId;				//< 主站定时广播SAMA模块参数信号量
sem_t* BcNetIOSemId;				//< 主站定时广播站间通讯模块DO、AO数据信号量
sem_t* CalcuSemId;					//< 各运算周期定时运算信号量



/*系统状态全局变量定义*/
SYS_Role_e SYS_Role;				//< 系统角色（未定义、主站且备站不存在、主站且备站存在、备站）
SYS_Status_e SYS_Status;			//< 系统状态（离线、正常运行、主从文件拷贝、等待文件、禁止命令下发）
NET_Status_e SYS_NetA_Status;		//< A网段状态（故障、正常）
NET_Status_e SYS_NetB_Status;		//< B网段状态（故障、正常）
NET_Status_e SYS_NetD_Status;		//< 104通讯网段状态（故障、正常）

NIC_Status_e SYS_NIC_ETHO_Status;   //< 3号网卡，ETH0状态（故障、正常）
NIC_Status_e SYS_NIC_ETH1_Status;   //< 4号网卡，ETH1状态（故障、正常）
NIC_Status_e SYS_NIC_ETH2_Status;   //< 2号网卡，ETH2状态（故障、正常）
NIC_Status_e SYS_NIC_ETH3_Status;   //< 1号网卡，ETH3状态（故障、正常）

bool SYS_ReadCard_Start = false;			//< 开始执行读卡线程（True/false）				//< duan191101 修改
bool SYS_Calcu_Start = false;				//< 开始执行运算线程（True/false）				//< duan191101 修改
bool SYS_BcORBak_Start = false;				//< 开始执行广播及备份线程（True/false）			//< duan191101 修改
short SYS_BaseTime;					//< 站基准周期，由上位下发得到（ms）   （数据库中设置）
unsigned char Station_ID;			//< 站号
unsigned char IPTail_Num;			//< IP地址最后一位      （txt中得到）
int DCS_TimeOut_Count;				//< DCS广播超时计数
bool SYS_SAMAIO_Start;				//< 开始执行SAMAIO通道写入线程（True/false）

//timespec BCIO_begin;     //< lijun20220723 测104通讯迟延 (发送)
//timespec BCIO_end;     //< lijun20220723 测104通讯迟延 (接收) 
//bool BCIO_flag = false;

//************************************
// Method:    	SYS_Role_Turn				系统角色切换并打印
// Programmer:  lww
// Time:		2019/3/7
// Returns:   	void
// Parameter: 	SYS_Role_e role				要切换到的系统角色
//************************************
void SYS_Role_Turn(SYS_Role_e role)
{
#define CASE(name)	case name:	printf(str, #name);	break
	const char str[] = "The system role is turned to %s\r\n";
	if (SYS_Role != role)
	{
		SYS_Role = role;
		switch (role)
		{
			CASE(Default_Role);
			CASE(Master_Alone_Role);
			CASE(Master_Twins_Role);
			CASE(Slave_Role);
		}
	}
#undef CASE
}

//************************************
// Method:    	SYS_Status_Turn				系统状态切换并打印
// Programmer:  lww
// Time:		2019/3/7
// Returns:   	void
// Parameter: 	SYS_Status_e status			要切换到的系统状态
//************************************
void SYS_Status_Turn(SYS_Status_e status)
{
#define CASE(name)	case name:	printf(str, #name);	break
	const char str[] = "The system status is turned to %s\r\n;";
	if (status != SYS_Status)
	{
		SYS_Status = status;
		switch (status)
		{
			CASE(Default_Status);
			CASE(Run_Status);
			CASE(File_Transfer_Status);
			CASE(File_Wait_Status);
			CASE(Forbid_Commend_Status);
		}
	}
#undef CASE
}

//************************************
// Method:    	Int2String					整数转化为字符串
// Programmer:  lww
// Time:		2019/7/14
// Returns:   	char*						存放字符串的数组的指针
// Parameter: 	int num						要转化的整数
// Parameter: 	char * str					存放字符串的数组的指针
// Parameter: 	int radix					转化为多少进制：2、8、10、16
//************************************
char* Int2String(int num, char* str, int radix)
{	/*索引表*/
	char index[] = "0123456789ABCDEF";
	unsigned unum;/*中间变量*/
	int i = 0, j, k;
	/*确定unum的值*/
	if (radix == 10 && num < 0)/*十进制负数*/
	{
		unum = (unsigned)-num;
		str[i++] = '-';
	}
	else unum = (unsigned)num;/*其他情况*/
	/*转换*/  //顺序相反 （123<int> --> 321<char *> ）
	do {
		str[i++] = index[unum % (unsigned)radix];
		unum /= radix;
	} while (unum);
	str[i] = '\0';
	/*逆序*/
	if (str[0] == '-')
		k = 1;/*十进制负数*/
	else
		k = 0;
	char temp;
	for (j = k; j <= (i - 1) / 2; j++)
	{
		temp = str[j];
		str[j] = str[i - 1 + k - j];
		str[i - 1 + k - j] = temp;
	}
	return str;
}